// 变扁 就是解决函子嵌套的问题。monad 函子可以变扁pointed函子。 IO(IO(x))
// 一个函子具有join和if两个方法，并遵守一些定律就是一个monad 函子
// 具有静态的IO方法，还有join的方法的 函子
// 当一个函数返回一个函子的时候，就想到moand
// 当我们想要合并一个函数 这个函数返回一个值 用map方法，当合并返回一个函子函数的时候 用flatMap
const fp = require ('lodash/fp')
const fs = require('fs') //node 的读取方法 fs模块
class Io {
    constructor (fn) {
        this._value = fn
    }
    static of(x) {
        return new Io (function() {
            return x
        })
    }
    join () {
        return this._value()
    }
    map(fn) {
        // 把当前得value 和传入得fn 组成一个新得函数
        return new Io (fp.flowRight(fn, this._value))
    }
    flatMap(fn) {
        return this.map(fn).join()
    }
}
// 读取文件
let readFile = function(filename) {
    return new Io(function() {
        return fs.readFileSync(filename, 'utf-8')
    })
}

let print = function (x) {
    return new Io(function() {
        return x
    })
}

let cat = readFile('package.json')
          .flatMap(print).map(fp.split('\n')).map(fp.find(x => x.includes('version')))
          .join()
console.log(cat)




